//
//  ViewController.m
//  adsx
//
//  Created by wp w on 12-6-15.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "ViewController.h"
#import "DLog.h"
#import "RunLoopSource.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.

    
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}


#pragma mark - RunLoopObserver
- (IBAction)RunLoopObserverTest {
    [NSThread detachNewThreadSelector:@selector(threadMain) toTarget:self withObject:nil];
}

- (void)threadMain
{
    // The application uses garbage collection, so no autorelease pool is needed.
    NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];
    
    // Create a run loop observer and attach it to the run loop.
    //设置Run loop observer的运行环境
    CFRunLoopObserverContext  context = {0, self, NULL, NULL, NULL};
    
    //创建Run loop observer对象  
    //第一个参数用于分配observer对象的内存  
    //第二个参数用以设置observer所要关注的事件，详见回调函数myRunLoopObserver中注释  
    //第三个参数用于标识该observer是在第一次进入run loop时执行还是每次进入run loop处理时均执行  
    //第四个参数用于设置该observer的优先级  
    //第五个参数用于设置该observer的回调函数  
    //第六个参数用于设置该observer的运行环境 
    CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault,
                                                            kCFRunLoopAllActivities, 
                                                            YES, 
                                                            0, 
                                                            &myRunLoopObserver, 
                                                            &context);
    
    if (observer)
    {
        //将Cocoa的NSRunLoop类型转换成Core Foundation的CFRunLoopRef类型 
        CFRunLoopRef cfLoop = [myRunLoop getCFRunLoop];
        //将新建的observer加入到当前thread的run loop 
        CFRunLoopAddObserver(cfLoop, observer, kCFRunLoopDefaultMode);
    }
    
    // Create and schedule the timer.
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self
                                   selector:@selector(doFireTimer:) userInfo:nil repeats:YES];
    
    NSInteger loopCount = 10;
    do
    {
        // Run the run loop 10 times to let the timer fire.
        //启动当前thread的loop直到所指定的时间到达，在loop运行时，run loop会处理所有来自与该run loop联系的input source的数据  
        //对于本例与当前run loop联系的input source只有一个Timer类型的source。  
        //该Timer每隔0.1秒发送触发事件给run loop，run loop检测到该事件时会调用相应的处理方法。  
        
        //由于在run loop添加了observer且设置observer对所有的run loop行为都感兴趣。  
        //当调用runUnitDate方法时，observer检测到run loop启动并进入循环，observer会调用其回调函数，第二个参数所传递的行为是kCFRunLoopEntry。  
        //observer检测到run loop的其它行为并调用回调函数的操作与上面的描述相类似。
        //当run loop的运行时间到达时，会退出当前的run loop。observer同样会检测到run loop的退出行为并调用其回调函数，第二个参数所传递的行为是kCFRunLoopExit。
        [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        DLog(@"loopCount:%d",loopCount);
        loopCount--;
    }
    while (loopCount);
}


void myRunLoopObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
{
    //    enum {
    //        kCFRunLoopEntry = (1UL << 0),
    //        kCFRunLoopBeforeTimers = (1UL << 1),
    //        kCFRunLoopBeforeSources = (1UL << 2),
    //        kCFRunLoopBeforeWaiting = (1UL << 5),
    //        kCFRunLoopAfterWaiting = (1UL << 6),
    //        kCFRunLoopExit = (1UL << 7),
    //        kCFRunLoopAllActivities = 0x0FFFFFFFU
    //    };
    //    typedef CFOptionFlags CFRunLoopActivity;
    DLogIntBinary(@"activity:", activity);
}

- (void)doFireTimer:(id)para{
    DLogFun();
}



RunLoopContext* loopContext;
NSThread* th;
#pragma mark - LoopSourceTest
- (IBAction)LoopSourceTest {    
    DLogStr(@"NSThread begin");
    th = [[NSThread alloc]initWithTarget:self selector:@selector(doLoopSourceTest:) object:self];
    [th start];
    DLogStr(@"NSThread in");
    [th release];
    DLogStr(@"NSThread end");
}

- (IBAction)invalidateTest {
    DLogFun();
    [loopContext.source performSelector:@selector(invalidate) onThread:th withObject:nil waitUntilDone:NO];
}

- (IBAction)removeTest {
    DLogFun();
    [loopContext.source performSelector:@selector(removeFromCurrentRunLoop) onThread:th withObject:nil waitUntilDone:NO];
}

- (void)doLoopSourceTest:(id)dele
{
    DLogStr(@"doLoopSourceTest begin");
    RunLoopSource *loopSource = [[RunLoopSource alloc]initWithDelegate:dele];
    [loopSource addToCurrentRunLoop];
    
    DLogStr(@"doLoopSourceTest in");
//    [loopSource release];
//    DLogStr(@"doLoopSourceTest end");
}

- (void)registerSource:(RunLoopContext*)sourceInfo;
{
    DLogFun();
    loopContext = sourceInfo;
    [sourceInfo.source addCommand:0 withData:@"0"];
//    [sourceInfo.source addCommand:0 withData:@"1"];
//    [sourceInfo.source addCommand:0 withData:@"2"];
//    [sourceInfo.source addCommand:0 withData:@"3"];
    
//    [sourcesToPing addObject:sourceInfo];
    [sourceInfo.source fireCommandsOnRunLoop];
}

- (void)removeSource:(RunLoopContext*)sourceInfo
{
    DLogFun();
    loopContext = sourceInfo;
//    id    objToRemove = nil;
//    
//    for (RunLoopContext* context in sourcesToPing)
//    {
//        if ([context isEqual:sourceInfo])
//        {
//            objToRemove = context;
//            break;
//        }
//    }
//    
//    if (objToRemove)
//        [sourcesToPing removeObject:objToRemove];
}

- (IBAction)logTest {


}

@end
